package com.javaclimb.accounting.service.impl;

import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement;
import com.javaclimb.accounting.dao.TradeDao;
import com.javaclimb.accounting.po.Trade;
import com.javaclimb.accounting.po.User;
import com.javaclimb.accounting.service.TradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.math.MathContext;
import java.sql.SQLException;
import java.util.concurrent.TimeoutException;


/**
 * @author xiaoming
 * @version jdk1.8
 * @date 2022/12/27 12:33
 * @function:
 */
@Service
@Transactional(isolation = Isolation.REPEATABLE_READ)
public class TradeServiceImpl implements TradeService {
    @Autowired
    private TradeDao tradeDao;

    /**
     * 根据用户名查询是否设置支付密码
     */
    @Override
    public boolean getUserPay(String userName) {
        String userPay = tradeDao.getUserPay(userName);
        if (userPay.equals("")||userPay.equals(null)){
            return false;
        }else {
            return true;
        }
    }
    /**
     * 根据用户名查询支付密码
     */
    @Override
    public String getPay(String userName) {
        return tradeDao.getUserPay(userName);
    }
    /**
     *设置支付密码
     */
    @Override
    public boolean insertPayPass(String userPay,String userName) {
        int i = tradeDao.insertPayPass(userPay, userName);
        if (i>0){
            return true;
        }else {
            return false;
        }
    }
    /**
     * 修改支付密码
     */
    @Override
    public int updateUserPay(String userName, String userPay) {
        return tradeDao.updateUserPay(userName,userPay);
    }

    /**
     *验证支付密码是否正确
     */
    @Override
    public boolean verifyUserPay(String userName, String userPay) {
        int i = tradeDao.verifyUserPay(userName, userPay);
        if (i>0){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 根据电子账户查询电子账户余额
     * @param accId 电子账户id
     * @return
     */
    @Override
    public BigDecimal getAccTempById(Long accId) {
        return tradeDao.getAccTempById(accId);
    }

    /**
     * 根据银行卡号查询电子账户余额
     * @param cardNumber 银行卡号
     * @return
     */
    @Override
    public BigDecimal getCardMoney(String cardNumber) {
        return tradeDao.getCardMoney(cardNumber);
    }

    /**
     * 提现扣减电子账户金额
     * @param money 提现金额
     * @param accId 电子账户Id
     * @param accTemp 电子账户余额
     */

    @Override
    public void withdrawal(BigDecimal money,Long accId,BigDecimal accTemp) throws Exception {
        tradeDao.withdrawal(money, accId, accTemp);
    }

    /**
     * 提现增加银行卡金额
     * @param money 提现金额
     * @param cardNumber 银行卡号
     * @param cardMoney 银行卡余额
     */
    @Override
    public void  withdrawalCard(BigDecimal money, String  cardNumber, BigDecimal cardMoney) throws Exception  {
        tradeDao.withdrawalCard(money,cardNumber,cardMoney) ;
    }

    /**
     * 提现后在trade表中添加记录
     * @param onCardId 银行卡id
     * @param onAccId 电子账户id
     * @param onMoney  交易金额
     * @param onBalance 账户余额
     * @return
     */
    @Override
    public void addTradeDrawal(Long onCardId, Long onAccId, BigDecimal onMoney, BigDecimal onBalance) throws Exception  {
        tradeDao.addTradeDrawal(onCardId, onAccId, onMoney, onBalance);

    }

    /**
     * 提现
     * @param money 提现金额
     * @param user user对象
     * @param cardNumber 银行卡号
     * @param tempNow 账户余额
     * @return
     */
    @Override
    public boolean drawal(BigDecimal money,User user,String cardNumber,BigDecimal tempNow)  {
            //提现减少电子账户金额
            try {
                withdrawal(money, user.getUserAccId(),tempNow);
                //再查询银行卡余额
                BigDecimal cardMoney = getCardMoney(cardNumber);
                BigDecimal cardMoneyNow = cardMoney.add(money, MathContext.UNLIMITED);
                //提现增加银行卡金额
                withdrawalCard(money, cardNumber, cardMoneyNow);
                //查询银行卡id
                Long onCardId = tradeDao.selectCardIdByCardNumber(cardNumber);
                addTradeDrawal(onCardId, user.getUserAccId(), money, tempNow);
            } catch (Exception e) {
                throw new RuntimeException();
            }
            return true;
        }


    /**
     * 充值  ysy
     */

//验证是否充值成功
    //验证是否充值成功
    @Override
    @Transactional(rollbackFor = Exception.class)
    /**
     * 接口 :http://localhost:8888/accounting/trade/isDeposit   post请求
     * //     * @param Long userAccId 用户表的电子账户id
     * //     * @param String cardNumber   银行卡号
     * //     * @param BigDecimal onMoney    交易金额
     */
    public int isDeposit(Long userAccId, String cardNumber, BigDecimal onMoney) {
        //验证是否设置支付密码
        //首先验证虚拟账户和支付密码是否正确
        //这个重复  user =tradeDao .selectUserAccIDAndUserPay(userAccId, userPay);
// 重复        if (user!=null){
        //根据银行卡号码去查银行卡余额

        try {
            //查询余额
            BigDecimal bigDecimal = tradeDao.selectCardMoney(cardNumber);

            int i = onMoney.compareTo(bigDecimal);
            //处理余额不足异常
            //System.out.println(i);
            int z = 1 / (i-1);

            int b = tradeDao.reduceCardMoney(cardNumber, onMoney);

            int a = tradeDao.AddAccTemp(userAccId, onMoney);

            //验证
            int num[] = new int[1];
            int y = num[(a + b) - 2];

            //     System.out.println(a);
            //查询银行卡id
            Long onCardId = tradeDao.selectCardIdByCardNumber(cardNumber);
            //查询当前电子账户余额
            BigDecimal onBalance = tradeDao.selectOnBalance(userAccId);
            //充值成功后往充值转账表中插入一条数据
            int i1 = addTrade(onCardId, userAccId, onMoney, onBalance);

            int[] f=new int[i1*2-1];

//            if (!(a != 0 && b != 0 && onCardId != null && onBalance != null && bigDecimal != null && i != 1)) {
//                //充值失败，抛异常
//                throw new Exception();
//            }
            return 1;
        } catch (ArithmeticException e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 2;   //余额不足
        } catch (ArrayIndexOutOfBoundsException e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 3;  //充值失败，钱已退回;
        }catch (NegativeArraySizeException e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 4;   //往充值提现表增加失败
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            System.out.println("超时异常");
            return 5;
        }
    }

    //往充值提现表中增加数据
    @Override
    public int addTrade(Long onCardId,Long onAccId,BigDecimal onMoney,BigDecimal onBalance) throws Exception{
        Trade trade=new Trade();//用一个实体类进行封装
        trade.setOnCardId(onCardId);//绑定银行卡id
        trade.setOnAccId(onAccId);//绑定的虚拟账户id
        trade.setOnMoney(onMoney);//交易金额
        //    trade.setOnTime(new Date());
        trade.setOnType("充值");
        trade.setOnBalance(onBalance);
        //调用dao层的方法
       return tradeDao.addTrade(trade);
    }

}
